package com.xbongbong.paas.connection.service.imp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.connection.enums.OpenAppEnum;
import com.xbongbong.paas.connection.help.HttpRequestUtils;
import com.xbongbong.paas.connection.pojo.mk.dto.OpenAppCallbackDTO;
import com.xbongbong.paas.connection.service.IOpenAppService;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ThirdPartyUsageErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.OpenAppApiTokenEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.ExpenseEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.domain.entity.ext.ReimbursementFormEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.ExpenseEnum;
import com.xbongbong.saas.enums.business.ReimbursementFormEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.ExpenseModel;
import com.xbongbong.saas.model.OpenAppApiTokenModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.ReimbursementFormModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.codec.digest.DigestUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

@Component
public class MeikeService implements IOpenAppService {

    private static final Logger LOG = LoggerFactory.getLogger(MeikeService.class);

    private static final String appCode = "XBB";
//    private static final String pwd = "123456";
    //正式环境配置
    private static final String pwd = "So2zrzlyp2TwMKwNvZ09zlGAoxSBe2w5";
    private static final String SUCCESS_CODE = "ACK";
    private static final String FAIL_CODE = "NACK";

//    private static final String LOGIN_URL = "https://dt-uat.maycur.com/api/openapi/auth/platform/login";
//    private static final String DATA_LIST = "https://dt-uat.maycur.com/api/openapi/platform/list";
    //正式环境配置
    private static final String LOGIN_URL = "https://dt.maycur.com/api/openapi/auth/platform/login";
    private static final String DATA_LIST = "https://dt.maycur.com/api/openapi/platform/list";

    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private OpenAppApiTokenModel openAppApiTokenModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private UserModel userModel;
    @Resource
    private ReimbursementFormModel reimbursementFormModel;
    @Resource
    private ExpenseModel expenseModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormModel paasFormModel;

    @Override
    public JSONObject getHeader() {
        String tokenId = getTokenId();
        JSONObject header = new JSONObject();
        header.put("appCode", appCode);
        header.put("tokenId", tokenId);
        return header;
    }

    @Override
    public void dataInit(String corpid) throws XbbException {


        JSONObject data = new JSONObject();
        data.put("entCode", getEntCode(corpid, OpenAppEnum.MEI_KE_BAO_XIAO.getOpenAppId()));
        data.put("referenceType","CUSTOMER");

        String ret = HttpRequestUtils.post(getHeader(), DATA_LIST, data.toJSONString());
    }

    @Override
    public JSONObject dataInitSchedule() {
        return null;
    }

    @Override
    public BaseVO openAppApiCallbackAccept(JSONObject jsonObject) throws XbbException {

        LOG.info("-------------openAppApiCallbackAccept-------------:" + jsonObject);

        OpenAppCallbackDTO openAppCallbackDTO = JSON.toJavaObject(jsonObject, OpenAppCallbackDTO.class);
        String formChangeType = openAppCallbackDTO.getFormChangeType();
        switch (formChangeType) {
            case "FORM_COMPLETE":
                formComplete(openAppCallbackDTO);
                break;
            case "FORM_DELETE":
                formDelete(openAppCallbackDTO);
                break;
            default:
                break;
        }
        return new BaseVO();
    }

    private void formComplete(OpenAppCallbackDTO openAppCallbackDTO) throws XbbException {
        String formDataCode = openAppCallbackDTO.getFormDataCode();
        String corpid = openAppCallbackDTO.getCorpid();
        String referenceType = openAppCallbackDTO.getReferenceTypes().get(0);
        //获取formDataCode对应的每刻
        ReimbursementFormEntityExt reimbursementFormEntityExt = getMkDataByFormDataCode(corpid, formDataCode, referenceType);

        ReimbursementFormEntityExt dbData = reimbursementFormModel.getByFormDataCode(corpid, formDataCode);
        if (Objects.isNull(dbData)) {
            mkDataAdd(reimbursementFormEntityExt);
        } else {
            //每刻那边只会更新报销单信息
            reimbursementFormEntityExt.setId(dbData.getId());
            reimbursementFormEntityExt.setUpdateTime(DateTimeUtil.getInt());
            reimbursementFormEntityExt.setAddTime(dbData.getAddTime());
            reimbursementFormModel.update(reimbursementFormEntityExt);
        }

    }

    /**
     * 添加报销单及其中的费用
     * @param reimbursementFormEntityExt
     * @throws XbbException
     * 创建时间 2020/3/16 3:01 PM
     * 修改时间 2020/3/16 3:01 PM
     * @author chy
     */
    private void mkDataAdd(ReimbursementFormEntityExt reimbursementFormEntityExt)  throws XbbException {
        List<ExpenseEntityExt> expenseEntityList = reimbursementFormEntityExt.getExpenseList();
        try {
            reimbursementFormModel.insert(reimbursementFormEntityExt);

            for (ExpenseEntityExt expenseEntity : expenseEntityList) {
                JSONObject data = expenseEntity.getData();
                data.put(ExpenseEnum.REIMBURSEMENT_FORM_ID.getAttr(), reimbursementFormEntityExt.getId());
                expenseEntity.setData(data);
            }
            expenseModel.insertBatch(expenseEntityList);
        } catch (Exception e) {
            LOG.error("mkDataAdd 数据保存失败，" + e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private ReimbursementFormEntityExt getMkDataByFormDataCode(String corpid, String formDataCode, String referenceType) throws XbbException {

        JSONObject requestData = new JSONObject();
        requestData.put("entCode", getEntCode(corpid, OpenAppEnum.MEI_KE_BAO_XIAO.getOpenAppId()));
        requestData.put("formDataCode",formDataCode);
        requestData.put("referenceType",referenceType);
        JSONObject header = getHeader();
        String ret = HttpRequestUtils.post(header, DATA_LIST, requestData.toJSONString());

//        String ret = "{\"code\":\"ACK\",\"bizCode\":null,\"message\":\"\",\"data\":{\"list\":[{\"formType\":\"REIMBURSE\",\"formDataCode\":\"BX2002251B32A3UO\",\"formName\":\"xbb测试11111\",\"formUserCode\":\"UI19030415VNJ18I\",\"formUserName\":null,\"departmentCode\":\"12345\",\"departmentName\":null,\"approvedAmount\":{\"amount\":100.00,\"currency\":\"CNY\",\"amountStr\":\"￥100.00\"},\"submitTime\":1583212320985,\"entLegalName\":\"杭州每时每刻有限公司\",\"expenseList\":[{\"expenseCode\":\"FD200303192O6UPS\",\"expenseType\":\"个人用餐\",\"consumeTime\":1583212647216,\"amount\":{\"amount\":100.00,\"currency\":\"CNY\",\"amountStr\":\"￥100.00\"},\"allocations\":[{\"projectName\":\"客户abc\",\"projectCode\":\"RDD2002272848NJ7K\",\"type\":\"\",\"dataId\":\"\",\"amount\":{\"amount\":50.00,\"currency\":\"CNY\",\"amountStr\":\"￥50.00\"}},{\"projectName\":\"客户abcd\",\"projectCode\":\"RDD20022921JEDYBK\",\"type\":\"CUSTOMER\",\"dataId\":\"3384612\",\"amount\":{\"amount\":50.00,\"currency\":\"CNY\",\"amountStr\":\"￥50.00\"}}]}]},{\"formType\":\"REIMBURSE\",\"formDataCode\":\"BX20022522D68C1S\",\"formName\":\"111\",\"formUserCode\":\"UI19030415VNJ18I\",\"formUserName\":null,\"departmentCode\":\"DI1910221XRLYA9D\",\"departmentName\":null,\"approvedAmount\":{\"amount\":11.00,\"currency\":\"CNY\",\"amountStr\":\"￥11.00\"},\"submitTime\":1582638669835,\"entLegalName\":\"杭州每时每刻有限公司\",\"expenseList\":[{\"expenseCode\":\"FD20022522CZOPA8\",\"expenseType\":\"454\",\"consumeTime\":1582639007322,\"amount\":{\"amount\":11.00,\"currency\":\"CNY\",\"amountStr\":\"￥11.00\"},\"allocations\":[{\"projectName\":\"e1我是名称2\",\"projectCode\":\"RDD2002151E5P2E4G\",\"type\":\"\",\"dataId\":\"\",\"amount\":{\"amount\":11.00,\"currency\":\"CNY\",\"amountStr\":\"￥11.00\"}}]}]}],\"totalCount\":2},\"args\":null,\"linkDetail\":false,\"nonBizError\":false}";

//        String ret = "{\"code\":\"ACK\",\"message\":\"\",\"data\":{\"list\":[{\"formType\":\"REIMBURSE\",\"formDataCode\":\"BX2003301TYG6JK0\",\"formName\":\"xbb测试3\",\"formUserCode\":\"180552014939930439\",\"departmentCode\":\"142351615\",\"approvedAmount\":{\"amount\":1111.00,\"currency\":\"CNY\",\"amountStr\":\"￥1,111.00\"},\"submitTime\":1585567156581,\"entLegalName\":\"%#%&&%\",\"expenseList\":[{\"expenseCode\":\"FD2003301TZ0C6IO\",\"expenseType\":\"过路费\",\"consumeTime\":1583407679932,\"amount\":{\"amount\":1111.00,\"currency\":\"CNY\",\"amountStr\":\"￥1,111.00\"},\"consumeCity\":\"北京市区-上海市区\",\"allocations\":[{\"projectName\":\"机会abcd\",\"projectCode\":\"RDD20022812B31OG0\",\"type\":\"OPPORTUNITY\",\"dataId\":\"112312\",\"amount\":{\"amount\":1111.00,\"currency\":\"CNY\",\"amountStr\":\"￥1,111.00\"}}]}]}],\"totalCount\":1},\"success\":true}";

        JSONObject json = JSON.parseObject(ret);

        if (!Objects.equals(json.getString("code"), SUCCESS_CODE)) {

            String message = json.getString("message");

            throw new XbbException(ThirdPartyUsageErrorCodeEnum.API_ERROR_900006, message);
        }

        JSONObject data = json.getJSONObject("data");
        JSONArray list = data.getJSONArray("list");

        if (Objects.isNull(list) || list.isEmpty()) {
            throw new XbbException(ThirdPartyUsageErrorCodeEnum.API_ERROR_900007);
        }

        JSONObject reimbursementFormJson = list.getJSONObject(0);

        ReimbursementFormEntityExt reimbursementFormEntity = formatReimbursementForm(corpid, reimbursementFormJson);

        return reimbursementFormEntity;
    }

    /**
     * 将每刻返回的信息转化成销帮帮这边的对象
     * @param json
     * @return
     * 创建时间 2020/3/7 4:32 PM
     * 修改时间 2020/3/7 4:32 PM
     * @author chy
     */
    private ReimbursementFormEntityExt formatReimbursementForm(String corpid, JSONObject json) throws XbbException {

        PaasFormEntityExt reimbursementFormPaasForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.REIMBURSEMENT_FORM.getCode(), corpid);
        PaasFormEntityExt expensePaasForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.EXPENSE.getCode(), corpid);

        if (Objects.isNull(reimbursementFormPaasForm) || Objects.isNull(expensePaasForm)) {
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }

        Long reimbursementFormMenuId = reimbursementFormPaasForm.getMenuId();
        Long reimbursementFormAppId = reimbursementFormPaasForm.getAppId();
        Long reimbursementFormFormId = reimbursementFormPaasForm.getId();
        Long expenseMenuId = expensePaasForm.getMenuId();
        Long expenseAppId = expensePaasForm.getAppId();
        Long expenseFormId = expensePaasForm.getId();

        Long now = DateTimeUtil.getInt();
        ReimbursementFormEntityExt reimbursementFormEntityExt = new ReimbursementFormEntityExt();

        String formType = json.getString("formType");
        String formSubType = json.getString("formSubTypeName");
        String formDataCode = json.getString("formDataCode");
        String formName = json.getString("formName");
        String formUserCode = json.getString("formUserCode");
        String formUserName = json.getString("formUserName");

        if (StringUtil.isEmpty(formUserName)) {
            UserEntity user = userModel.getByKey(formUserCode, corpid);
            formUserName = Objects.isNull(user) ? "" : user.getName();
        }

        Long departmentCode = json.getLong("departmentCode");
        String departmentName = json.getString("departmentName");
        JSONObject approvedAmountJson = json.getJSONObject("approvedAmount");
        Double approvedAmount = approvedAmountJson.getDouble("amount");
        Long submitTime = json.getLong("submitTime")/1000L;
        String entLegalName = json.getString("entLegalName");

        reimbursementFormEntityExt.setCorpid(corpid);
        reimbursementFormEntityExt.setAppId(reimbursementFormAppId);
        reimbursementFormEntityExt.setMenuId(reimbursementFormMenuId);
        reimbursementFormEntityExt.setFormId(reimbursementFormFormId);
        reimbursementFormEntityExt.setSerialNo(formDataCode);
        reimbursementFormEntityExt.setOwnerId(formUserCode);
        reimbursementFormEntityExt.setDepartmentId(departmentCode);
        reimbursementFormEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
        reimbursementFormEntityExt.setCreatorId(formUserCode);
        reimbursementFormEntityExt.setAddTime(now);
        reimbursementFormEntityExt.setUpdateTime(now);
        reimbursementFormEntityExt.setDel(BasicConstant.ZERO);

        JSONObject reimbursementFormData = new JSONObject();
        reimbursementFormData.put(ReimbursementFormEnum.OPEN_APP_ID.getAttr(), OpenAppEnum.MEI_KE_BAO_XIAO.getOpenAppId());
        reimbursementFormData.put(ReimbursementFormEnum.FORM_TYPE.getAttr(), formType);
        reimbursementFormData.put(ReimbursementFormEnum.FORM_SUB_TYPE.getAttr(), formSubType);

        reimbursementFormData.put(ReimbursementFormEnum.FORM_NAME.getAttr(), formName);
        reimbursementFormData.put(ReimbursementFormEnum.FORM_USER_CODE.getAttr(), formUserCode);
        reimbursementFormData.put(ReimbursementFormEnum.FORM_USER_NAME.getAttr(), formUserName);
        reimbursementFormData.put(ReimbursementFormEnum.APPROVED_AMOUNT.getAttr(), approvedAmount);
        reimbursementFormData.put(ReimbursementFormEnum.ENT_LEGAL_NAME.getAttr(), entLegalName);
        reimbursementFormData.put(ReimbursementFormEnum.SUBMIT_TIME.getAttr(), submitTime);


        List<ExpenseEntityExt> expenseEntityList = new ArrayList<>();

        JSONArray expenseList = json.getJSONArray("expenseList");
        Set<String> referenceTypeSet = new HashSet<>();
        for (Object expense : expenseList) {
            JSONObject expenseJson = (JSONObject)expense;
            String expenseCode = expenseJson.getString("expenseCode");
            String expenseType = expenseJson.getString("expenseType");
            String consumeCity = expenseJson.getString("consumeCity");
            Long consumeTime = expenseJson.getLong("consumeTime")/1000L;
            JSONObject expenseAmountJson = expenseJson.getJSONObject("amount");
            Double expenseAmount = expenseAmountJson.getDouble("amount");
            JSONArray allocations = expenseJson.getJSONArray("allocations");
            for (Object allocation : allocations) {
                JSONObject allocationJson = (JSONObject)allocation;
//                String projectName = allocationJson.getString("projectName");
                String projectCode = allocationJson.getString("projectCode");
                String type = allocationJson.getString("type");
                String dataIdStr = allocationJson.getString("dataId");
                Long dataId = StringUtil.StringToLong(dataIdStr);
                JSONObject apportionedAmountJson = allocationJson.getJSONObject("amount");
                Double apportionedAmount = apportionedAmountJson.getDouble("amount");
                ExpenseEntityExt expenseEntityExt = new ExpenseEntityExt();
                expenseEntityExt.setCorpid(corpid);
                expenseEntityExt.setAppId(expenseAppId);
                expenseEntityExt.setMenuId(expenseMenuId);
                expenseEntityExt.setFormId(expenseFormId);
                expenseEntityExt.setSerialNo(expenseCode);
                expenseEntityExt.setOwnerId(formUserCode);
                expenseEntityExt.setDepartmentId(departmentCode);
                expenseEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
                expenseEntityExt.setCreatorId(formUserCode);
                expenseEntityExt.setAddTime(now);
                expenseEntityExt.setUpdateTime(now);
                expenseEntityExt.setDel(BasicConstant.ZERO);

                JSONObject expenseData = new JSONObject();
                expenseData.put(ExpenseEnum.OPEN_APP_ID.getAttr(), OpenAppEnum.MEI_KE_BAO_XIAO.getOpenAppId());

                //没有保存之前，报销单ID还获取不到
//                expenseData.put(ExpenseEnum.REIMBURSEMENT_FORM_ID.getAttr(), formDataCode);
                expenseData.put(ExpenseEnum.LINK_REIMBURSEMENT_FORM_HIDE.getAttr(), formDataCode);
                expenseData.put(ExpenseEnum.EXPENSE_TYPE.getAttr(), expenseType);
                expenseData.put(ExpenseEnum.CONSUME_CITY.getAttr(), consumeCity);
                expenseData.put(ExpenseEnum.AMOUNT.getAttr(), expenseAmount);
                expenseData.put(ExpenseEnum.CONSUME_TIME.getAttr(), consumeTime);
                expenseData.put(ExpenseEnum.FORM_USER_CODE.getAttr(), formUserCode);
                expenseData.put(ExpenseEnum.FORM_USER_NAME.getAttr(), formUserName);

                String projectName = setBusinessInfo(corpid, expenseData, type, dataId);

                expenseData.put(ExpenseEnum.PROJECT_NAME.getAttr(), projectName);
                expenseData.put(ExpenseEnum.PROJECT_CODE.getAttr(), projectCode);

                expenseData.put(ExpenseEnum.APPORTIONED_AMOUNT.getAttr(), apportionedAmount);
                referenceTypeSet.add(type);
                expenseEntityExt.setData(expenseData);
                expenseEntityList.add(expenseEntityExt);
            }
        }

        reimbursementFormData.put(ReimbursementFormEnum.REFERENCE_TYPE.getAttr(), JSON.toJSONString(referenceTypeSet));
        reimbursementFormEntityExt.setData(reimbursementFormData);

        reimbursementFormEntityExt.setExpenseList(expenseEntityList);

        return reimbursementFormEntityExt;
    }

    /**
     * 设置销帮帮关联业务
     * @param corpid
     * @param expenseData 费用data
     * @param type  业务类型，CUSTOMER,CONTRACT,OPPORTUNITY
     * @param dataId 客户id/机会id/合同id
     * 创建时间 2020/3/31 3:53 PM
     * 修改时间 2020/3/31 3:53 PM
     * @author chy
     */
    private String setBusinessInfo(String corpid, JSONObject expenseData, String type, Long dataId) throws XbbException {
        if (StringUtil.isEmpty(type)) {
            return "";
        }

        String projectName = "";

        switch (type) {
            case "CUSTOMER":
                expenseData.put(ExpenseEnum.CUSTOMER_ID.getAttr(), dataId);
                CustomerEntityExt customer = customerModel.getByKey(dataId, corpid);
                if (Objects.isNull(customer)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
                }
                projectName = customer.getData().getString(CustomerManagementEnum.NAME.getAttr());
                expenseData.put(ExpenseEnum.LINK_CUSTOMER_ID_HIDE.getAttr(), projectName);
                break;
            case "OPPORTUNITY":
                expenseData.put(ExpenseEnum.OPPORTUNITY_ID.getAttr(), dataId);
                OpportunityEntityExt opportunity = opportunityModel.getByKey(dataId, corpid);
                if (Objects.isNull(opportunity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
                }
                projectName = opportunity.getData().getString(SalesOpportunityEnum.NAME.getAttr());
                expenseData.put(ExpenseEnum.LINK_OPPORTUNITY_ID_HIDE.getAttr(), projectName);
                break;
            case "CONTRACT":
                expenseData.put(ExpenseEnum.CONTRACT_ID.getAttr(), dataId);
                ContractEntityExt contract = contractModel.getByKey(dataId, corpid);
                if (Objects.isNull(contract)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
                }
                projectName = contract.getData().getString(ContractEnum.NAME.getAttr());
                expenseData.put(ExpenseEnum.LINK_CONTRACT_ID_HIDE.getAttr(), projectName);
                break;
            default:
                break;
        }
        return projectName;
    }

    /**
     * 报销单删除
     * @param openAppCallbackDTO
     */
    private void formDelete(OpenAppCallbackDTO openAppCallbackDTO) throws XbbException {

        LOG.info("---------formDelete----------");
        LOG.info("openAppCallbackDTO:" + openAppCallbackDTO);
        String corpid = openAppCallbackDTO.getCorpid();
        String formDataCode = openAppCallbackDTO.getFormDataCode();

        ReimbursementFormEntityExt reimbursementForm = reimbursementFormModel.getByFormDataCode(corpid, formDataCode);

        if (Objects.isNull(reimbursementForm)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
        }
        LOG.info("reimbursementForm not null");
        //获取报销单下所有的费用记录
        List<Long> expenseIdList = getExpenseIdByReimbursementFormCode(corpid, reimbursementForm.getDataId());
        LOG.info("expenseIdList.size:" + expenseIdList.size());
        if (!expenseIdList.isEmpty()) {
            LOG.info("expenseIdList not null");
            //删除报销单下的所有费用
            expenseModel.deleteBatch(expenseIdList, corpid);
            //删除报销单
            reimbursementFormModel.deleteByKey(reimbursementForm.getId(), corpid);
        }
    }


    /**
     * 获取报销单下费用的id集合
     * @param corpid 公司id
     * @param reimbursementFormId 报销单编号
     * @return
     * @throws XbbException
     * 创建时间 2020/3/16 6:33 PM
     * 修改时间 2020/3/16 6:33 PM
     * @author chy
     */
    private List<Long> getExpenseIdByReimbursementFormCode(String corpid, Long reimbursementFormId) throws XbbException {
        String esData = StringConstant.JSON_DATA + StringConstant.POINT;
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(esData + ExpenseEnum.REIMBURSEMENT_FORM_ID.getAttr(), reimbursementFormId));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
//        fieldList.add(StringConstant.JSON_DATA);
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_EXPENSE,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        List<Long> expenseIdList = new ArrayList<>();
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
            expenseIdList.add(paasFormDataEntityExt.getDataId());
        }
        return expenseIdList;
    }

    /**
     * 获取每刻的entCode
     * @param corpid 公司id
     * @param openAppId 每刻的应用id
     * @return
     * @throws XbbException
     */
    private String getEntCode(String corpid, Integer openAppId) throws XbbException {
        OpenAppApiTokenEntity openAppApiTokenEntity = openAppApiTokenModel.getByKey(openAppId, corpid);

        if (Objects.isNull(openAppApiTokenEntity)) {
            throw new XbbException(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001, String.format(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001.getMsg(), OpenAppEnum.MEI_KE_BAO_XIAO.getName()));
        }

        String tokenDataStr  = openAppApiTokenEntity.getTokenData();

        JSONObject tokenData = null;
        try {
            tokenData = JSON.parseObject(tokenDataStr);
        } catch (Exception e) {
            //同tokenData = null判断
        }

        if (Objects.isNull(tokenData)) {
            throw new XbbException(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001, String.format(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001.getMsg(), OpenAppEnum.MEI_KE_BAO_XIAO.getName()));
        }

        String entCode = tokenData.getString("entCode");

        if (StringUtil.isEmpty(entCode)) {
            throw new XbbException(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001, String.format(ThirdPartyUsageErrorCodeEnum.API_ERROR_900001.getMsg(), OpenAppEnum.MEI_KE_BAO_XIAO.getName()));
        }

        return entCode;
    }

    private String getTokenId(){

        //从缓存获取
        String tokenId = paasRedisHelper.getValue(RedisPrefixConstant.OPEN_TOKEN, OpenAppEnum.MEI_KE_BAO_XIAO.getAlias());
        if (!StringUtil.isEmpty(tokenId)) {
            return tokenId;
        }

        Long timestamp = DateUtil.getLong();
        String secret = DigestUtils.sha256Hex(pwd + ":" + appCode + ":" + timestamp);

        JSONObject data = new JSONObject();
        data.put("secret", secret);
        data.put("appCode", appCode);
        data.put("timestamp", timestamp);

        String ret = HttpRequestUtils.post(null, LOGIN_URL, data.toJSONString());
        if (StringUtil.isEmpty(ret)) {
            return null;
        }

        JSONObject retJson = JSON.parseObject(ret);
        String code = retJson.getString("code");
        if (!Objects.equals(code, "ACK")) {
            LOG.error("getTokenId error ret:" + ret);
            return null;
        }
        JSONObject meikeData = retJson.getJSONObject("data");
        if (Objects.isNull(meikeData)) {
            LOG.error("getTokenId error ret:" + ret);
            return null;
        }
        tokenId = meikeData.getString("tokenId");
        //每刻的tokenId有效时间2小时，这边设置为7000秒
        paasRedisHelper.setValue(RedisPrefixConstant.OPEN_TOKEN, "meike", tokenId, 7000);
        return tokenId;
    }

    @Override
    public void requestCheck(HttpServletRequest httpRequest, JSONObject data) throws XbbException {
        Integer openAppId = StringUtil.toInt(httpRequest.getHeader("openAppId"), null);
        Integer sysOpenAppId = OpenAppEnum.MEI_KE_BAO_XIAO.getOpenAppId();
        if (!Objects.equals(openAppId, sysOpenAppId)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "openAppId错误");
        }
    }
}
